





#ifndef __DEV_MOTOR__H__
#define __DEV_MOTOR__H__



#include"stl_.h"


// 角度模式，加减速的步数是固定的，只保存加减速节点的值。
// 速度模式，只有加速，这里的步数也是可以固定的。再留一个变量，保存是否加速中即可。

#define motor_timer_us    100   // 定时器时间间隔。微秒为单位。按照下面的频率分析，定时器间隔100us也能满足需求。     
#define motor_ACC_Time_s  0.2   // 1加速的时间，单位是秒（可以设置成浮点数，如0.5f）
#define motor_MAX_frequency  400  // 脉冲最大频率，单位Hz。默认610，脉冲周期1.6ms。
#define motor_MIN_frequency  20   // 脉冲最小频率，单位Hz。默认20，脉冲周期50ms。   //




//  定时间隔要求： motor_timer_us < (1,000,000 / motor_MAX_frequency) / 5

/// <summary>
/// 调用间隔 Timer_us 单位，微秒。
/// 这里不计算具体的角度，只计算步进电机的步数。（具体的角度与步进电机参数有关）
/// 如果定时器调用是5us,最快是10us一步，即每秒100k步。 一般的步进电机转速不可能这么快。      
/// </summary>
typedef struct _steper_motor__
{
	unt32 timer_count;		 // 定时器调用次数计数

	int mode;   // 0：以步数为准，1：以频率为准。
	//  2：停止模式。 只有停止的时候可以修改模式。   
	// 步数为准的模式，频率一直是0。
	// 频率为准的模式，在停止的时候会将current_step同步到target_step，new_step，防止停止的时候，自动切换到步数模式，自动回退。

	nt32 max_step; // 大部分步进电机的机构里，比如丝杆，会存在一个运动的极限。这里就是步数上限。
	nt32 min_step; // 同理，也会有步数的下限。

	int breke_step;  // 刹车步数。= target_frequency *  motor_ACC_Time_s，这里预留两倍。在极限步数前要刹车，避免损坏，在设置目标频率的时候计算，步进电机的时钟里要判断刹车距离。

	int target_step;     // 设定角度对应的步数。这里设定最大是 2,000,000,000 步。大于这个值是无效的值。设定角度，会默认运行到最大速度
	int new_step;        // 新设置的步数只有到达了前面的步数，这个新步数才会生效。
	int current_step;    // 当前的步数。
	int start_step;      // 在变换角度的时候用，记录起始的角度。

	int target_frequency; // 脉冲目标频率，单位Hz。默认600
	int new_frequency;    // 加速过程中不能变化目标频率，如果要变化，先记录到这个缓存中。如果单独设置速度，会取消target_step的值。
	int current_frequency; // 当前的频率。
	int start_frequency; // 在变换速度的时候用。速度是s型变化的，自然要记录起始速度。

	// 下面是驱动引脚电平相关的变量
	bool io_enable;   // 使能引脚。当mode == 2 停止模式的时候，enable = 0，步进电机休眠，减少发热。步进的时候enable没有使能，会先使能，下一个时钟再步进。
	bool io_pulse;    // 脉冲引脚，默认低电平。这里设定，一个高电平脉冲步进一步。
	bool io_dir;      // 方向引脚。如果频率是正的，方向就是true。

	bool new_dir;     // 新设置的方向。在刷新步数和频率的时候，存储新的方向。如果方向相反，需要先反转方向，下一个时钟再步进。
	bool is_step;     // 是否步进一步。这里不管频率多少，脉冲宽度都是motor_timer_us。 如果需要步进一步，将这个变量设为false即可。 
	unt32 timer_count_io_pulse_down;  // 脉冲的io口设置50%的占空比，这个变量记录脉冲io恢复低电平的 定时器计数timer_count。
	unt32 timer_count_next_step;  // 下一个周期时间。
}steper_motor;
//

/// <summary>
/// 初始化步进电机
/// </summary>
/// <param name="steper_motor">步进电机结构体</param>
void steper_motor_init(steper_motor* sm);


/// <summary>
/// 在定时器中调用。
/// 定时间隔要求 motor_timer_us < (1,000,000 / motor_MAX_frequency) / 5
/// </summary>
/// <param name="sm">步进电机的结构体</param>
void steper_motor_clock(steper_motor* sm);
//





// 测试加速度曲线的函数值。
void test_moto_curve(void);

// 测试通过，生成的周期都是没问题的。
void test_get_pulse_period(void);

// 下面测试步进电机驱动代码。
void test_steper_motor(void);

//测试三角函数快速计算形式（查表法计算）
void test_fast_sin(void);













#endif // !__DEV_MOTOR__H__



